package com.eastfair.auth.service;

import com.alibaba.fastjson.JSONObject;
import com.eastfair.auth.dto.HuaWeiAccountDTO;
import com.eastfair.auth.dto.HuaWeiOrganizationDTO;
import com.eastfair.auth.dto.OrganizationDTO;
import com.eastfair.auth.entity.MenuRole;
import com.eastfair.auth.entity.OrganizationRole;
import com.eastfair.auth.enumeration.OrganizationOrgTypeEnum;
import com.eastfair.auth.enumeration.OrganizationVestTypeEnum;
import com.eastfair.auth.enumeration.ResourceOrganizationResourceTypeEnum;
import com.eastfair.auth.vo.DataTreeVo;
import com.eastfair.auth.vo.OrganizationVo;
import com.eastfair.auth.vo.RoleVo;
import com.eastfair.boot.service.SuperCacheService;
import com.eastfair.auth.entity.Organization;
import com.eastfair.core.base.R;
import com.eastfair.projectcore.vo.MenuVO;
import org.springframework.beans.BeanUtils;

import java.util.List;
import java.util.Map;

/**
 * <p>
 * 业务接口
 *
 * </p>
 *
 * @author ligang
 * @date 2021-07-16
 */
public interface OrganizationService extends SuperCacheService<Organization> {

    /**
     * 删除,并删除旗下所有子节点
     *
     * @param id 节点id
     * @return
     */
    R del(Long id);

    /**
     * 删除子节点
     *
     * @param organization 节点实体
     * @return
     */
    R delChild(Organization organization);


    /**
     * 获取排序值
     *
     * @param parentId 父级id
     * @return
     */
    int querySort(Long parentId);

    /**
     * 获取code值
     *
     * @param organization 节点实体
     * @return
     */
    String queryCode(Organization organization);

    /**
     * 排序置顶
     *
     * @param id 主键id
     */
    public void sortTop(Long id);


    /**
     * 初始化排序
     *
     * @param parentId 父级id
     */
    public void initSort(Long parentId);


    /**
     * 查询code相关的所有信息
     *
     * @param organizationDTO code码
     * @return
     */
    List<Organization> queryAllOfCode(OrganizationDTO organizationDTO);

    /**
     * 查询code相关的所有信息
     *
     * @param orgIds code码
     * @return
     */
    List<Organization> queryAllOfCode(List<Long> orgIds);

    /**
     * 查询code相关的所有信息数量
     *
     * @param code code码
     * @return
     */
    int queryCodeSize(String code);

    /**
     * 加载数据成树状结构
     *
     * @param parentCode         根code码
     * @param organizationVoList 节点集合
     * @return
     */
    OrganizationVo loadTree(String parentCode, List<OrganizationVo> organizationVoList);


    /**
     * 创建节点
     *
     * @param organizationDTO 节点新增实体
     * @return
     */
    R<Organization> createOrg(OrganizationDTO organizationDTO);


    /**
     * 修改节点
     *
     * @param organizationDTO 修改节点实体
     * @return
     */
    R<Organization> updOrg(OrganizationDTO organizationDTO);

    /**
     * 查询子集信息，只查一层子集
     *
     * @param parentId 父级id
     * @return
     */
    List<Organization> queryEntityOfParentId(Long parentId);

    /**
     * 查询节点信息和全部子信息
     *
     * @param id 节点id
     * @return
     */
    OrganizationVo findAllById(Long id);

    /**
     * 查询节点信息和全部子信息(只查组织结构)
     *
     * @param id 节点id
     * @return
     */
    OrganizationVo findAllByIdNoResource(Long id);


    /**
     * 查询节点信息(全局查數據)
     *
     * @param organizationList 节点id
     * @return
     */
    List<OrganizationVo> queryOrgNoResource(List<Organization> organizationList);

    /**
     * 查询组织列表
     *
     * @param organization 节点实体属性
     * @param ids          节点id集合
     * @return
     */
    List<Organization> listOfOrganization(Organization organization, List<Long> ids);

    /**
     * 方便缓存用
     *
     * @param organization
     * @param ids
     * @return
     */
    List<Organization> listOfOrganizationOfCache(Organization organization, List<Long> ids);

    /**
     * 添加组织关联角色
     *
     * @param orgId        节点id
     * @param roleIds      角色id集合
     * @param isConduction 是否传导到旗下所有子节点
     * @return
     */
    R addOrgRole(Long orgId, List<Long> roleIds, boolean isConduction);

    /**
     * 添加组织关联角色
     *
     * @param parentOrgId 父节点id
     * @param menuIds     菜单id集合
     * @return
     */
    R verifyMenuIsOver(Long parentOrgId, List<Long> menuIds);


    /**
     * 更新组织关联角色
     *
     * @param orgId        节点id
     * @param roleIds      角色id集合
     * @param isConduction 是否传导到旗下所有子节点
     * @return
     */
    R updOrgRole(Long orgId, List<Long> roleIds, boolean isConduction);

    /**
     * 剔除节点关联的角色
     *
     * @param orgId        节点id
     * @param roleIds      角色id集合
     * @param isConduction 是否传导到旗下所有子节点
     * @return
     */
    R removeOrgRole(Long orgId, List<Long> roleIds, boolean isConduction);


    /**
     * 清空节点的角色
     *
     * @param orgId 节点id
     * @return
     */
    R removeOrgRole(Long orgId);


    /**
     * 剔除关联的角色
     *
     * @param roleIds 角色id集合
     * @return
     */
    R removeOfRole(List<Long> roleIds);


    /**
     * 装载菜单信息
     *
     * @param roleVoList 角色Vo集合
     * @return
     */
    List<MenuVO> loadMenu(List<RoleVo> roleVoList);

    /**
     * 装载菜单信息
     *
     * @param roleVoList 角色Vo集合
     * @return
     */
    List<MenuVO> loadMenuNoButton(List<RoleVo> roleVoList);

    /**
     * 装载菜单信息
     *
     * @param roleVoList 角色Vo集合
     * @return
     */
    List<MenuVO> loadMenuAll(List<RoleVo> roleVoList);

    /**
     * 装载菜单信息
     *
     * @param roleVoList 角色Vo集合
     * @return
     */
    Map<Long, List<MenuVO>> loadMenuOfMap(List<RoleVo> roleVoList);

    /**
     * 查询菜单关联角色信息
     *
     * @param roleVoList 角色Vo集合
     * @return
     */
    List<MenuRole> loadMenuRole(List<RoleVo> roleVoList);

    /**
     * 装载角色信息
     *
     * @param orgIds 组织节点id集合
     * @return
     */
    List<RoleVo> loadRole(List<Long> orgIds);

    /**
     * 装载角色的权限标识信息
     *
     * @param roleVoList
     * @return
     */
    Map<String, List<String>> loadMenuPermission(Long userId, List<RoleVo> roleVoList);

    /**
     * 装载角色信息
     *
     * @param orgIds 组织节点id集合
     * @return
     */
    Map<Long, List<RoleVo>> loadRoleOfMap(List<Long> orgIds);

    /**
     * 全量剔除组织关联的资源和用户
     *
     * @param orgIds 组织节点id集合
     * @return
     */
    R removeResourceUserOfOrg(List<Long> orgIds);


    /**
     * 查询节点的所有的菜单和功能
     *
     * @param orgId 组织节点id
     * @return
     */
    OrganizationVo findMenuOrFunctionById(Long orgId);


    /**
     * 查询 项目下的类型节点信息
     *
     * @param type
     * @param parentOrgId 父节点id
     * @return
     */
    Organization queryOrgOfType(OrganizationOrgTypeEnum type, Long parentOrgId);

    /**
     * 查询 项目下的类型节点信息
     *
     * @param type
     * @param resourceId
     * @param resourceType
     * @return
     */
    Organization queryOrgOfTypeAndResource(OrganizationOrgTypeEnum type, Long resourceId, ResourceOrganizationResourceTypeEnum resourceType);

    /**
     * 查询 父节点下的类型节点信息集合
     *
     * @param parentCode 父节点 code码
     * @param type
     * @return
     */
    List<Organization> queryOrgTypeOfParent(String parentCode, OrganizationOrgTypeEnum type);

    /**
     * 查询 父节点下的节点名称筛选
     *
     * @param parentCode 父节点 code码
     * @param orgName    节点名称
     * @return
     */
    List<Organization> queryOrgNameOfParent(String parentCode, String orgName);


    /**
     * 校验资源是否在组织里面存在
     *
     * @param organizationDTO 必传值 orgId 组织id
     *                        resourceId 资源id
     */
    Organization verifyResourceExistOfOrg(OrganizationDTO organizationDTO);


    /**
     * 通过资源查询角色Id集合
     *
     * @param resourceId
     * @return
     */
    List<Long> queryRoleOfResourceId(Long resourceId);

    /**
     * 查询资源指定节点下的组织Id集合
     *
     * @param resourceId
     * @param orgId
     * @return
     */
    List<Long> queryOrgOfResourceId(Long resourceId, Long orgId);


    /**
     * 查询资源指定节点下的组织集合
     *
     * @param resourceIds
     * @param orgIds
     * @return
     */
    Map<Long, List<Organization>> queryOrgVoOfResourceId(List<Long> resourceIds, List<Long> orgIds);


    /**
     * 添加资源到多个组织里
     *
     * @param resourceId 资源id
     * @param orgIds     节点id
     * @return
     */
    R addResourceOfOrgIds(Long resourceId, List<Long> orgIds, ResourceOrganizationResourceTypeEnum resourceType);


    /**
     * 删除指定节点下的资源
     *
     * @param resourceId 资源id
     * @param orgId      指定节点
     * @return
     */
    R delResource(Long resourceId, Long orgId);


    /**
     * 查询用户权限信息，用于接口判断
     *
     * @param userIdList
     * @return
     */
    List<Map> loadUserPermission(List<Long> userIdList);


    /**
     * 根据组织查询用户的权限信息，用于接口判断
     *
     * @param orgIdList
     * @return
     */
    List<Map> loadUserPermissionOfOrg(List<Long> orgIdList);

    /**
     * 根据角色查组织进而查询用户的权限信息，用于接口判断
     *
     * @param roleIdList
     * @return
     */
    List<Map> loadUserPermissionOfRole(List<Long> roleIdList);


    /**
     * 检验是否有权限
     *
     * @param userId
     * @param permission      方法注解
     * @param classPermission 类注解
     * @return
     */
    Boolean isPermission(Long userId, String[] permission, String[] classPermission);


    /**
     * 查询节点全部子节点iD
     *
     * @param orgIds 节点id
     * @return
     */
    List<Long> queryOrgChildId(List<Long> orgIds);

    /**
     * 根据用户查询组织信息
     *
     * @param userIds
     * @return
     */
    Map<Long, List<Organization>> queryOrgOfUserId(List<Long> userIds);


    /**
     * 通过用户查询菜单id
     *
     * @param userId 用户id
     * @return
     */
    List<Long> queryMenuIdOfUser(Long userId);


    /**
     * 初始化项目组织和角色
     */
    List<Organization> initOrgAndRole(OrganizationDTO organizationDTO);

    /**
     * 初始化项目级别枚举类组织
     */
    List<Organization> initOrgOfProject(OrganizationDTO organizationDTO);

    /**
     * 初始化资源级别枚举类组织
     */
    List<Organization> initOrgOfResource();


    /**
     * 查找资源所在的节点信息（资源池组织）
     *
     * @param resourceId 资源id
     * @return
     */
    List<Organization> findResource(OrganizationOrgTypeEnum type, OrganizationVestTypeEnum vestType, Long parentOrgId, Long resourceId);

    /**
     * 剔除节点超级管理员
     *
     * @param orgId 资源id
     * @return
     */
    R breakUseridOfOrg(Long orgId, List<Long> userIds);

    /**
     * 添加资源节点员工
     *
     * @param orgId    组id
     * @param userIds  用户id
     * @param isLeader 是否是组管理员
     * @return
     */
    R addUseridOfOrg(Long orgId, List<Long> userIds, Integer isLeader);

    /**
     * 加载用户和资源
     *
     * @param organizationVoList
     */
    void loadUserAndResource(List<OrganizationVo> organizationVoList);

    OrganizationVo doToVo(Organization organization);

    List<OrganizationVo> doToVos(List<Organization> organizationList);


    /**
     * 组装成前端的树
     *
     * @param organizationVo
     * @return
     */
    DataTreeVo assemblyTree(OrganizationVo organizationVo);


    /**
     * 同步华为的账号数据
     *
     * @param huaWeiOrganizationDTO
     * @return
     */
    HuaWeiOrganizationDTO sycnOrgOfCreate(HuaWeiOrganizationDTO huaWeiOrganizationDTO);

    /**
     * 同步华为的账号数据
     *
     * @param huaWeiOrganizationDTO
     * @return
     */
    HuaWeiOrganizationDTO sycnOrgOfUpd(HuaWeiOrganizationDTO huaWeiOrganizationDTO);


    /**
     * 同步华为的账号数据
     *
     * @param huaWeiOrganizationDTO
     * @return
     */
    HuaWeiOrganizationDTO sycnOrgOfDel(HuaWeiOrganizationDTO huaWeiOrganizationDTO);
}
